#include <miaux.h>
#include <shader.h>

using namespace lofi::miaux;

////////////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS

Color::Color()
{
	myColor.r = 1.0f;
	myColor.g = 1.0f;
	myColor.b = 1.0f;
	myColor.a = 1.0f;
}

Color::Color(float value)
{
	myColor.r = value;
	myColor.g = value;
	myColor.b = value;
	myColor.a = value;
}

Color::Color(float r, float g, float b)
{
	myColor.r = r;
	myColor.g = g;
	myColor.b = b;
	myColor.a = 1.0f;
}

Color::Color(float r, float g, float b, float a)
{
	myColor.r = r;
	myColor.g = g;
	myColor.b = b;
	myColor.a = a;
}

Color::Color(miColor &color)
{
	myColor.r = color.r;
	myColor.g = color.g;
	myColor.b = color.b;
	myColor.a = color.a;
}

Color::Color(const Color &color)
{
	if (this != &color)
	{
		myColor.r = color.myColor.r;
		myColor.g = color.myColor.g;
		myColor.b = color.myColor.b;
		myColor.a = color.myColor.a;
	}
}

// END OF CONSTRUCTORS
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// OPERATOR OVERLOADS

///////////////////////////////////////
// COLOR - COLOR
Color& Color::operator=(const Color& rhs)
{
	if (this != &rhs)
	{
		myColor.r = rhs.myColor.r;
		myColor.g = rhs.myColor.g;
		myColor.b = rhs.myColor.b;
		myColor.a = rhs.myColor.a;
	}
	return *this;
}

bool Color::operator==(const Color& rhs) const
{
	if (myColor.r == rhs.myColor.r &&
		myColor.g == rhs.myColor.g &&
		myColor.b == rhs.myColor.b &&
		myColor.a == rhs.myColor.a)
		return true;
	else
		return false;
}

Color& Color::operator+=(const Color &rhs)
{
	myColor.r += rhs.myColor.r;
	myColor.g += rhs.myColor.g;
	myColor.b += rhs.myColor.b;
	myColor.a += rhs.myColor.a;
	return *this;
}

Color& Color::operator-=(const Color &rhs)
{
	myColor.r -= rhs.myColor.r;
	myColor.g -= rhs.myColor.g;
	myColor.b -= rhs.myColor.b;
	myColor.a -= rhs.myColor.a;
	return *this;
}

Color& Color::operator*=(const Color &rhs)
{
	myColor.r *= rhs.myColor.r;
	myColor.g *= rhs.myColor.g;
	myColor.b *= rhs.myColor.b;
	myColor.a *= rhs.myColor.a;
	return *this;
}

Color& Color::operator/=(const Color &rhs)
{
	myColor.r /= rhs.myColor.r;
	myColor.g /= rhs.myColor.g;
	myColor.b /= rhs.myColor.b;
	myColor.a /= rhs.myColor.a;
	return *this;
}

Color& Color::operator%=(const Color &rhs)
{
	myColor.r = fmod(myColor.r, rhs.myColor.r);
	myColor.g = fmod(myColor.g, rhs.myColor.g);
	myColor.b = fmod(myColor.b, rhs.myColor.b);
	myColor.a = fmod(myColor.a, rhs.myColor.a);
	return *this;
}
// COLOR - COLOR
///////////////////////////////////////

///////////////////////////////////////
// COLOR - FLOAT
Color& Color::operator=(const float& rhs)
{
	myColor.r = rhs;
	myColor.g = rhs;
	myColor.b = rhs;
	myColor.a = rhs;
	return *this;
}

Color& Color::operator+=(const float &rhs)
{
	myColor.r += rhs;
	myColor.g += rhs;
	myColor.b += rhs;
	myColor.a += rhs;
	return *this;
}

Color& Color::operator-=(const float &rhs)
{
	myColor.r -= rhs;
	myColor.g -= rhs;
	myColor.b -= rhs;
	myColor.a -= rhs;
	return *this;
}

Color& Color::operator*=(const float &rhs)
{
	myColor.r *= rhs;
	myColor.g *= rhs;
	myColor.b *= rhs;
	myColor.a *= rhs;
	return *this;
}

Color& Color::operator/=(const float &rhs)
{
	myColor.r /= rhs;
	myColor.g /= rhs;
	myColor.b /= rhs;
	myColor.a /= rhs;
	return *this;
}

Color& Color::operator%=(const float &rhs)
{
	myColor.r = fmod(myColor.r, rhs);
	myColor.g = fmod(myColor.g, rhs);
	myColor.b = fmod(myColor.b, rhs);
	myColor.a = fmod(myColor.a, rhs);
	return *this;
}
// COLOR - FLOAT
///////////////////////////////////////

// END OF OPERATOR OVERLOADS
////////////////////////////////////////////////////////////////////////////////

void Color::blend(const Color A, const Color B, miScalar amount)
{
	*this = ((A * amount) + (B * (1.0 - amount)));
}

miScalar Color::R()
{
	return myColor.r;
}

miScalar Color::G()
{
	return myColor.g;
}

miScalar Color::B()
{
	return myColor.b;
}

miScalar Color::A()
{
	return myColor.a;
}

void Color::R(miScalar r)
{
	myColor.r = r;
}

void Color::G(miScalar g)
{
	myColor.g = g;
}

void Color::B(miScalar b)
{
	myColor.b = b;
}

void Color::A(miScalar a)
{
	myColor.a = a;
}
